// https://juejin.cn/post/7158786701249216519
import { Button } from 'infosysD';
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';

interface IProps {}

// currentTarget就是绑定事件的那个元素
// target是用户点击的那个元素

const TapEvent: FC<IProps> = (props) => {
  const [visible, setVisible] = useState(false);

  const close = useCallback(() => {
    setVisible(false);
  }, []);

  // useEffect(() => {
  //   document.body.addEventListener('click', close, false);
  //   return () => {
  //     document.body.removeEventListener('click', close, false);
  //   };
  // }, []);

  const handleClickFather = (e: MouseEvent<HTMLDivElement>) => {
    console.log(e.currentTarget, 'effffff');
  };
  const handleClick = (e: MouseEvent<HTMLDivElement>) => {
    console.log((e.nativeEvent.target as HTMLDivElement).style, 'eeeeeee');
  };

  useEffect(() => {
    const tpl = document.querySelector('#localEvent');
    if (tpl) {
      tpl.addEventListener('click', (e) => {
        e.stopPropagation();
      });
    }
    const tpl2 = document.querySelector('#uniEvent');
    if (tpl2) {
      tpl2.addEventListener('click', (e) => {
        console.log('uniEventuniEventuniEvent');
      });
    }
  }, []);

  return (
    <div>
      <div onClick={handleClickFather}>
        father
        <div onClick={handleClick} className="ccccccc">
          child
        </div>
        <div className="thirdItem">33333</div>
      </div>
      <br />
      <div>
        <Button
          onClick={(e) => {
            setVisible(true);
          }}
        >
          点我显示弹窗
        </Button>
        {visible && (
          <div style={{ width: 100, height: 100, background: 'blue' }}>
            我是弹窗
          </div>
        )}
      </div>
      <div
        onClick={() => {
          console.log('原生事件father');
        }}
      >
        <div id="localEvent">原生事件（阻止冒泡）会阻止合成事件的执行</div>
      </div>
      <div id="uniEvent">
        <div
          onClick={(e) => {
            e.stopPropagation();
          }}
        >
          合成事件（阻止冒泡）不会阻止原生事件的执行
        </div>
      </div>
      <br />
      <div id="target">
        <div
          id="currentTarget"
          onClick={(e) => {
            console.log(e.nativeEvent.target, e.nativeEvent.currentTarget);
            // console.log(e.target, e.currentTarget);
            console.log(e);
          }}
        >
          currentTarget
        </div>
      </div>
    </div>
  );
};
export default TapEvent;

// https://juejin.cn/post/7185317161408299068
// 原生事件: 在 componentDidMount生命周期里边进行addEventListener绑定的事件
// 合成事件: 通过 JSX 方式绑定的事件，比如 onClick={() => this.handle()}
// 浏览器事件的执行需要经过三个阶段，捕获阶段-目标元素阶段-冒泡阶段。
// Question: 此时对于合成事件进行阻止，原生事件会执行吗？答案是: 会！
//  Answer: 因为原生事件先于合成事件执行 (个人理解: 注册的原生事件已经执行，而合成事件处于目标阶段，它阻止的冒泡只是阻止合成的事件冒泡，但是原生事件在捕获阶段就已经执行了)

/**
 * React 自己实现了这么一套事件机制，它在 DOM 事件体系基础上做了改进，减少了内存的消耗，并且最大程度上解决了 IE 等浏览器的不兼容问题
那它有什么特点？
React 上注册的事件最终会绑定在document这个 DOM 上，而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上，其他节点没有绑定事件)
React 自身实现了一套事件冒泡机制，所以这也就是为什么我们 event.stopPropagation() 无效的原因。
React 通过队列的形式，从触发的组件向父组件回溯，然后调用他们 JSX 中定义的 callback
React 有一套自己的合成事件 SyntheticEvent，不是原生的，这个可以自己去看官网
React 通过对象池的形式管理合成事件对象的创建和销毁，减少了垃圾的生成和新对象内存的分配，提高了性能
 */

/**
 * e.stopImmediatePropagation() 相当于e.stopPropagation()的增强版，不但可以阻止向上的冒泡，还能够阻止同级的扩散
 * 原生事件（阻止冒泡）会阻止合成事件的执行   合成事件（阻止冒泡）不会阻止原生事件的执行
 */
